package com.nuyoah.controller;


import cn.dev33.satoken.stp.StpUtil;
import com.nuyoah.common.dto.LoginDto;
import com.nuyoah.common.dto.RoleDto;
import com.nuyoah.common.dto.UserDto;
import com.nuyoah.common.lang.Result;
import com.nuyoah.entity.User;
import com.nuyoah.service.RoleService;
import com.nuyoah.service.StudentService;
import com.nuyoah.service.TeacherService;
import com.nuyoah.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户接口
 *
 * @author xyx
 * @since 2024-06-03
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;


    @Autowired
    private RoleService roleService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private TeacherService teacherService;


    /**
     * 用户登录接口。
     * 通过@RequestBody注解将登录Dto对象绑定到方法参数上，以接收前端发送的登录请求数据。
     * 请求映射到/login路径，用于处理用户的登录请求。
     *
     * @param loginDto 登录请求数据，包含用户身份和认证信息。
     * @return 返回登录结果，如果成功，包含登录后的用户信息；否则，包含错误信息。
     */
    //登录接口
    @RequestMapping("/login")
    public Result login(@RequestBody LoginDto loginDto) {
        // 根据用户身份决定使用哪种服务进行登录验证
        if (loginDto.getIdentity().equals("student")) {
            UserDto user = studentService.login(loginDto);
            // 返回登录结果，如果登录成功，user将不为null。
            return Result.succ(user);
        }
        if (loginDto.getIdentity().equals("teacher")) {
            UserDto user = teacherService.login(loginDto);
            // 返回登录结果，如果登录成功，user将不为null。
            return Result.succ(user);
        }
        if (loginDto.getIdentity().equals("admin")) {
            User user = userService.login(loginDto);
            // 返回登录结果，如果登录成功，user将不为null。
            return Result.succ(user);
        }
        // 如果身份不正确，则返回错误信息
        return Result.fail("身份不正确");
    }

    /**
     * 处理用户退出登录的请求。
     * 该方法通过调用STP（Single Token Pattern）工具类的logout方法来实现用户的退出登录操作。
     * 主要逻辑是清除用户的登录状态，确保用户不能再访问需要登录才能访问的资源。
     *
     * @return Result 对象，表示退出登录的操作结果。成功退出时，返回一个包含成功消息的结果对象。
     */
    //退出登录接口
    @RequestMapping("/logout")
    public Result logout() {
        // 调用STP工具类的logout方法，实现用户退出登录
        StpUtil.logout();
        // 返回成功结果，告知用户退出登录操作成功
        return Result.succ("退出成功");
    }

    /**
     * 获取用户列表的请求处理方法。
     * <p>
     * 通过此方法，前端可以通过发送请求到/list来获取用户的列表信息。
     * 使用@RequestMapping注解来映射请求URL，确保请求路径与方法的一致性。
     * 返回的Result对象包含操作结果和用户列表数据，成功时，数据部分为userService.getUserList()的返回值。
     *
     * @return Result 对象，其中包含操作结果（成功或失败）以及用户列表数据。
     */
    //获取用户列表
    @RequestMapping("/list")
    public Result getUserList() {
        return Result.succ(userService.getUserList());
    }


    /**
     * 获取用户信息接口。
     * 通过该接口，客户端可以获取当前登录用户的详细信息，包括用户名、用户ID以及角色名称。
     *
     * @return Result 对象，包含操作结果和用户角色信息。如果操作成功，Result 的数据部分将是用户角色的 DTO 对象。
     */
    //获取用户信息
    @RequestMapping("/info")
    public Result getUserInfo() {
        Integer ids = StpUtil.getLoginIdAsInt();
        ;
        //通过id到用户表中查询用户信息
        User user = userService.getUserById(ids);
        // 如果用户不存在，则返回错误信息
        if (user == null) {
            return Result.fail("用户不存在");
        }
        // 获取用户的ID，用于进一步查询学生详细信息
        Integer id = user.getId();
        // 创建一个新的RoleDto对象，用于包装用户的角色信息
        RoleDto roleDto = new RoleDto();
        // 将用户的用户名和ID赋值给RoleDto对象
        roleDto.setUsername(user.getUsername());
        roleDto.setId(user.getId());
        // 通过角色服务，根据用户ID获取角色名称，并设置到RoleDto对象中
        //根据id到用户角色关联表中查询角色id，再根据角色id到角色表中查询角色名称
        roleDto.setRoleName(roleService.getRoleNameByUserId(id));
        // 返回操作结果，包含用户角色的DTO对象
        return Result.succ(roleDto);
    }

    /**
     * 添加用户接口。
     * 通过@RequestBody注解，将请求体中的用户信息绑定到方法参数user上。
     * 接口调用成功后，返回添加用户的操作结果。
     *
     * @param user 待添加的用户对象，包含用户的所有信息。
     * @return 添加用户操作的结果，成功则包含新用户的ID等信息。
     */
    //添加用户接口
    @RequestMapping("/add")
    public Result addUser(@RequestBody User user) {
        return Result.succ(userService.addUser(user));
    }

    /**
     * 修改用户接口。
     * 通过@RequestBody注解，将请求体中的用户信息绑定到方法参数user上。
     * 接口调用成功后，返回修改用户操作的结果。
     *
     * @param user 待修改的用户对象，包含用户的所有信息以及要修改的新值。
     * @return 修改用户操作的结果，成功则可能包含修改后的用户信息。
     */
    //修改用户接口
    @RequestMapping("/update")
    public Result updateUser(@RequestBody User user) {
        return Result.succ(userService.updateUser(user));
    }

    /**
     * 删除用户接口。
     * 通过@RequestParam注解，将请求参数中的用户ID绑定到方法参数id上。
     * 接口调用成功后，返回删除用户操作的结果。
     *
     * @param id 待删除用户的ID。
     * @return 删除用户操作的结果，成功则可能不返回具体信息。
     */
    //删除用户接口
    @RequestMapping("/delete")
    public Result deleteUser(@RequestParam("id") Integer id) {
        return Result.succ(userService.deleteUser(id));
    }

    /**
     * 检查用户是否存在。
     * 通过用户的ID查询用户是否存在，如果存在返回成功结果，否则返回失败结果。
     *
     * @param id 用户ID，用于查询用户是否存在。
     * @return Result 对象，包含查询结果的成功或失败状态。
     */
    //根据用户id判断用户是否存在
    @RequestMapping("/exist")
    public Result existUser(@RequestParam("id") Integer id) {
        return Result.succ(userService.existUser(id));
    }
}
